/**
 * Resource Timing 规范定义了接口用于访问文档中资源文件的完整时间数据。
 *    用户等待时长是web应用的一个重要质量指标。基于JavaScript的测量机制，可以提供全面的用户等待时长
 * 测量结果，多数情况下，可以提供完整的端到端等待视图。这篇规范里定义的 PerformanceResourceTiming
 * 接口允许JavaScript测量和收集完整的当前文档内的资源文件时间数据。Navigation Timing API 扩展了
 * 被规范，提供了额外的关于导航的时序信息。
 */

// 下面的例子展示了如何测量获取一个资源耗费的时间
const example1 = () => {
  let start = new Date().getTime();
  let img1 = new Image();
  const resourceTiming = () => {

  let resourceList = window.performance.getEntriesByType('resource');
  for(i = 0; i < resourceList.length; i += 1) {
    if(resourceList[i].initiatorType === 'img') {
      console.log(`End to end resource fetch: ${resourceList[i].responseEnd - resourceList[i].startTime}`);
    }
  }

    document.body.appendChild(img1);
  }
  img1.onload = resourceTiming;
  img1.src = `https://10.43.167.19:3011/images/img_1.jpg`;
}
example1();

/**
 * 资源时序
 *    PerformanceResourceTIming 接口让测量可下载资源时间更加便利，可测量内容包括：XMLHttpRequest请求、
 * HTML元素（iframe,img,script,object,embed,link(type="text/stylesheet")、svg等。
 *    
 *    ·如果两个img标签使用相同的url，那么第一个 img 元素获取时会创建 PerformanceResourceTiming对象
 *     保存在 performance 中。这种情况下，UA 不一定会重新请求第二个img，而是使用已经存在初始下载。
 *     这样 performance 中只会保存一次时序信息。
 *    
 *    ·如果一个img元素的src属性通过脚本发生了变化，那么变化前后的时序信息都会保存在performance中
 * 
 *    ·如果通过标记写入一个 iframe 元素，src属性没有设置，UA 会给入宇哥 about:blank 文档。如果
 *     随后通过脚本动态修改了 src 属性，UA 会为 ifram 获取新的文档。此时，只有新文档的资源请求会
 *     保存进 performance。
 * 
 *    ·如果使用同一个地址生成了两次XHR请求，那么这两次资源的获取都会保存在 proformance 中。因为第二次
 *     请求无法复用第一次请求的下载。
 * 
 *    ·如果页面上的 iframe 的资源请求保存在 performance 中了，iframe 文档中的资源获取会保存在 iframe
 *     的 performance 对象中，而不是父级文档的 performance。
 * 
 *    ·如果一个 img 元素的 src 是数据路径(data:url)，则不会保存在 performance 对象中。因为数据路径
 *     不会发起资源获取。
 * 
 *    ·如果一个资源获取因网络问题中断了，那么这个获取也许会被保存在 performance 对象中，并携带在中断
 *     前完成了初始化的属性和值。
 * 
 *    ·如果一个资源获取因预处理（内容混合、跨域限制等）的原因中断时，不应保存在 performance 对象中。
 */

/**
 * PerformanceResourceTiming 接口
 *    继承了 PerformanceEntry 接口部分字段 {
 *        name: 返回请求资源的解析后的 URL。
 *        entryType: 默认为 'resource'
 *        startTime: 是 UA 开始序列化请求的时间。如果存在 HTTP 重定向，并且 timing allow check 算法通过，这个属性返回与 redirectStart 相同的值，否则返回与 fetchStart 相同的值
 *        duration: 返回 startTime 和 responseEnd 之间的差值。
 *    }
 *    扩展了 PerformaceEntry 接口
 * [Exposed = (Window, Worker)]
 * interface PerformacnceResourceTiming : PerformanceEntry {
 *    readonly attribute DOMString initiatorType: 必须返回这些值中的一种(css/navigation/xmlhttprequest/fetch/beacon/other/某种元素名)
 *    readonly attribute DOMString nextHopProtocol: 请求当前资源使用的协议
 *    readonly atrribute HRTS workerStart: 如果当前上下文中没有激活的工作进行，则该值为0。如果有，返回这个可用的工作进程第一次触发 fetch 事件前的时间
 *    readonly attribute HRTS redirectStart: 如果获取资源时有 HTTP 重定向行为，并且 timing allow check 算法通过，则返回开始冲顶现象前的时间点，否则为0
 *    ... redirectEnd: 在带有重定向的资源请求中，并且 timing allow check 算法通过时，返回最后一个重定向完成且收取到最后一个数据字节后的时间点
 *    ... fetchStart: 如果资源请求带有重定向，则返回开始获取重定向中最后一个资源前的时间点，否则为开始获取该资源前的时间点。
 *    ... domainLookupStart: 如果 timing allow check 算法未通过，则返回0。如果没有域名解析需要的话则与 fetchStart 相同，如果有，则再看 UA 是否缓存了域名信息，如果有缓存，则值为开始检索域名信息缓存的时间点，如果没有，则是开始域名解析前的时间点。
 *    ... domainLookupEnd: 如果 timing allow check 算法未通过，则返回0。如果没有域名解析需要则与 fetchStart 相同，如果又，则再看是否有域名信息缓存，如果有缓存，则该值为域名信息解析完成后的时间点，如果没有，则为UA完成域名解析的时间点。
 *    ... connectStart: 如果 timing allow check 算法未通过，则返回0.如果连接已存在，或者资源来自本地链接或缓存则值与 fetchStart 相同，否则值为 UA 与资源服务建立连接开始前的时间点。
 *    ... connectEnd: 如果 timing allow check 算法为通过，则返回0。如果当前连接已存在，或者资源来自本地或缓存则值与 fetchStart 相同，否则值为 UA 与资源服务端建立连接完成的时间点。
 *    ... secureConnectionStart: 如果没有使用安全传输，或者资源没有通过 timing allow check 算法，则值为0。如果连接已攒在或者资源来自本地和缓存，则值与 fetchStart 相同。否则，值为 UA 与安全连接握手处理前的时间点。
 *    ... requestStart: 如果 timing allow check 算法通过，则值为 UA 开始请求资源前的时间点。如果连接中断，UA 重新发送请求，字段值也相应为新请求的相关值。否则为0.
 *    ... responseStart: 如果 timgin allow check 算法通过，则值为 UA 的 HTTP 解析器收到第一个相应数据字节前的时间点，否则为0
 *    ... responseEnd: 如果请求因网络原因中断，则值为当前时间点，否则值为 UA 收到相应数据最后一个字后后的事件点，或者是传输连接中断前的时间点，这两个时间点最终取值看那个先。
 *    readonly attribute unsigned long long transferSize: HTTP 获取到的8位字节数据大小。包括响应头字段和相应体，如果请求带有重定向则还要包含重定向请求的内容。如果资源来自缓存和本地则值为0.
 *    ... encodedBodySize: HTTP 获取到的8位字节数据大小，数据来自保留所有内容编码的载荷体。
 *    ... decodedBodySize: HTTP 获取到的8位字节数据大小，数据来自解码后的载荷体。
 * }
 */

/**
 * UA 可能会限制保存的 PerformanceResourceTiming 对象个数，推荐的最小个数为 250，当然 UA 可以更改这一限制
 * 通过扩展 Performance 接口，定义了控制 PerformanceResourceTiming 对象数量的方法
 *    partial interface Performance {
 *        void clearResourceTiming(): 删除所有保存的 PerformanceResourceTiming 对象
 *        void setResourceTimingBUfferSize(unsigned long maxSize): 设置全局对象下资源时间缓冲大小限制字段最大值为给入的参数，如果参数小于当前值，则不会有变化
 *    }
 */

/**
 * Tips: 
 *    如果资源请求跨域，默认所有时序信息值均为0，如果需要这些数据，则要求远端服务器添加 Timing-Allow-Origin 响应头字段，
 * 值与 Access-Control-Allow-Origin 相似。
 */

/**
 * 时间顺序；
 * [startTime,(redirectStart)]                         [(connectEnd,requestStart)] 
 *    |                        [(domainLookupStart)]   |                        [responseEnd]
 *    |                       |                        |                       |
 *    ---------- -------------  ----------- ----------- -----------------------
 *    |redirect| |  AppCache | |    DNS   | |   TCP   | | Request |  Response |
 *    ---------- ------------- -----------  ----------- -----------------------
 *             |                          |                       |
 *             |                          |                       [(responseStart)]
 *             [fetchStart,(redirectEnd)] |
 *                                        [(domainLookUpEnd,connectStart,secureConnectionStart)]
 */